using System;
using System.Collections.Generic;
using System.IO;

abstract class FileSystemObject
{
public string Name { get; set; }
public Directory Parent { get; set; }
public string Type { get; set; }

public FileSystemObject(string name, Directory parent, string type)
{
Name = name;
Parent = parent;
Type = type;
}

public string GetPath()
{
return Parent == null ? Name : Parent.GetPath() + "/" + Name;
}
}

class File : FileSystemObject
{
public File(string name, Directory parent) : base(name, parent, "datne") { }
}

class Directory : FileSystemObject
{
public Dictionary<string, FileSystemObject> Children { get; set; }

public Directory(string name, Directory parent) : base(name, parent, "mape")
{
Children = new Dictionary<string, FileSystemObject>();
}

public void AddChild(FileSystemObject obj)
{
if (Children.ContainsKey(obj.Name))
throw new Exception($"Objekts ar nosaukumu '{obj.Name}' jau eksistē.");
Children[obj.Name] = obj;
}

public void RemoveChild(string name)
{
if (!Children.ContainsKey(name))
throw new Exception($"Nav atrasts: {name}");
Children.Remove(name);
}

public void ListChildren()
{
foreach (var child in Children.Values)
{
Console.WriteLine(child.Type == "mape" ? $"/[{child.Name}]" : $"/~[{child.Name}]");
}
}

public FileSystemObject GetChild(string name)
{
return Children.ContainsKey(name) ? Children[name] : null;
}
}

class Program
{
static Directory root = new Directory("c:", null);
static Directory current = root;

static void Main()
{
Console.WriteLine("Failu Sistēma sākta. Lieto 'exit' lai izietu.");

while (true)
{
Console.Write(current.GetPath() + "> ");
var input = Console.ReadLine().Trim();
if (string.IsNullOrEmpty(input)) continue;
if (input.ToLower() == "exit" || input.ToLower() == "by") break;

var parts = input.Split(' ', 2);
var command = parts[0].ToLower();
var args = parts.Length > 1 ? parts[1].Split(' ', StringSplitOptions.RemoveEmptyEntries) : new string[0];

try
{
switch (command)
{
case "mkdir":
foreach (var name in args) current.AddChild(new Directory(name, current));
break;

case "create":
foreach (var name in args) current.AddChild(new File(name, current));
break;

case "rm":
foreach (var name in args)
{
var child = current.GetChild(name);
if (child is Directory dir)
{
if (dir.Children.Count > 0)
{
Console.Write($"Mapei '{name}' ir bērni. Dzēst? (j/n): ");
if (Console.ReadLine().ToLower() != "j") continue;
}
current.RemoveChild(name);
Console.WriteLine($"Mape '{name}' izdzēsta.");
}
}
break;

case "del":
foreach (var name in args)
{
var child = current.GetChild(name);
if (child is File)
{
current.RemoveChild(name);
var filePath = $"{name}.txt";
if (File.Exists(filePath)) File.Delete(filePath);
Console.WriteLine($"Datne '{name}' izdzēsta.");
}
}
break;

case "cd":
if (args[0] == ".." && current.Parent != null)
current = current.Parent;
else if (args[0] == "/")
current = root;
else
{
var next = current.GetChild(args[0]) as Directory;
if (next != null) current = next;
else Console.WriteLine("Mape nav atrasta.");
}
break;

case "dir":
if (args.Length > 0 && args[0].StartsWith(">"))
{
var fileName = args[0].Substring(1);
var filePath = fileName + ".txt";
using (StreamWriter sw = new StreamWriter(filePath))
{
foreach (var child in current.Children.Values)
{
sw.WriteLine(child.Name);
}
}

if (current.GetChild(fileName) is File) current.RemoveChild(fileName);
current.AddChild(new File(fileName, current));
Console.WriteLine($"Bērni saglabāti datnē '{filePath}'.");
}
else current.ListChildren();
break;

case "edit":
var fileToEdit = args[0];
var editPath = fileToEdit + ".txt";
if (File.Exists(editPath))
{
Console.WriteLine($"Saturs no '{editPath}':");
Console.WriteLine(File.ReadAllText(editPath));
}
else Console.WriteLine("Datne nav atrasta.");
break;

default:
Console.WriteLine("Nezināma komanda.");
break;
}
}
catch (Exception ex)
{
Console.WriteLine("Kļūda: " + ex.Message);
}
}

Console.WriteLine("Programma izbeigta.");
}
}